<!--
 * @Author: huangtianyang 916072572@qq.com
 * @Date: 2023-05-29 10:14:26
 * @LastEditors: huangtianyang
 * @LastEditTime: 2023-08-02 15:19:02
 * @FilePath: \cxl-h5\src\components\validateInput\Index.vue
-->
<template>
    <render></render>
</template>
<script setup lang="ts">
import { h, ref, watchEffect } from 'vue'
import {
    CheckSocialCreditCode,
    checkEmail,
    checkPassword,
    checkSpecialPlane,
    regBankAccount,
    regMobile
} from '@/utils/index'

const props = defineProps([
    'modelValue',
    'required',
    'type',
    'checkType',
    'bgColor',
    'textColor',
    'round',
    'border',
    'clearable',
    'showPassword',
    'placeholder',
    'errorText',
    'errTxt',
    'describeText',
    'submit',
    'contarst' //只能传 true 或者不传 passCheck
])
const emits = defineEmits(['update:modelValue', 'blur'])

/**
 *  <section>
 *     <section>
 *         <section class="left-content">
 *             <i>*<i/>
 *             <p>标题</p>
 *         </section>
 *         <section class='right-content'>
 *             <section class='input-box'>
 *                  <input class='inputStyle' />
 *                  <section class='icon-box'>
 *                      <section class='icon-item' @click=''>
 *                          <section class='icon-content'>
 *                              <span class="icon-box iconfont icon-eye"></span>
 *                          </section>
 *                      </section>
 *                  </section>
 *             </section>
 *             <section class='describe'>
 *                 <section class='hint'>描述性文字</section>
 *                 <section class='err'>错误提示</section>
 *             </section>
 *         </section>
 *     </section>
 *  </section>
 */

//名称
const title = ref('')
//是否有标题
// const hasTitle = ref(true)
//是否是必填项
const isRequired = ref(false)
//定义输入框是否激活
const inputFocusActive = ref(false)
//输入框的类型
const inputType = ref('text')
//输入框的值
const inputVal = ref('')
//输入框背景色
const bgColor = ref('')
//文本颜色
const textColor = ref('')
//是否有border
const border = ref(false)
//是否是圆角
const round = ref(false)
//icon 显示隐藏
const iconVisible = ref(false)
//当前输入框存在的icon clear(清除内容) password（显示/隐藏密码）
const hasIcon = ref(false)
//clear(清除内容)
const clearable = ref(false)
//密码是否显示
const showPassword = ref(false)
//input 元素实例
const inputRef = ref()
//输入框输入提示语
const placeholder = ref('')
//校验错误提示语
const errorText = ref('')
//描述性文案
const describeText = ref('')
//校验输入文本类型
const checkType = ref('')
//是否通过校验
const isPassCheck = ref(true)
//对比
const contarst = ref(false)
//是否改变了input 类型
const isInputTypeChange = ref(false)
//默认值
// const defaultValue = ref('')

//校验方法
const validateInput = () => {
    let t = ''
    isPassCheck.value = true
    if (isRequired.value) {
        if (!inputVal.value.length) {
            isPassCheck.value = false
            if (checkType.value === 'password' || checkType.value === 'loginPassword') {
                t = '密码不能为空！'
            } else if (checkType.value === 'phone') {
                t = '手机号不能为空！'
            } else if (checkType.value === 'code') {
                t = '验证码不能为空！'
            }
        }
    }
    if (inputVal.value.length) {
        if (checkType.value === 'phone') {
            isPassCheck.value = regMobile(inputVal.value)
            t = '手机号码有误，请重新输入！'
        } else if (checkType.value === 'loginPassword') {
            isPassCheck.value = checkPassword(inputVal.value)
            t = '密码格式有误，请重新输入！'
        } else if (checkType.value === 'socialCreditCode') {
            isPassCheck.value = CheckSocialCreditCode(inputVal.value)
            t = '税号有误，请重新输入！'
        } else if (checkType.value === 'bank') {
            isPassCheck.value = regBankAccount(inputVal.value)
            t = '银行卡号有误，请重新输入！'
        } else if (checkType.value === 'email') {
            isPassCheck.value = checkEmail(inputVal.value)
            t = '电子邮箱格式有误，请重新输入！'
        } else if (checkType.value === 'tel') {
            isPassCheck.value = checkSpecialPlane(inputVal.value)
            t = '电话格式有误，请重新输入！'
        }
    }
    errorText.value = t ? t : props.errorText
    return isPassCheck.value
}

watchEffect(() => {
    isRequired.value = props.required === undefined ? false : props.required === '' ? true : props.required
    border.value = props.border === undefined ? false : props.border === '' ? true : props.border
    round.value = props.round === undefined ? false : props.round === '' ? true : props.round
    bgColor.value = props.bgColor != undefined ? props.bgColor : ''
    textColor.value = props.textColor != undefined ? props.textColor : ''
    if (!isInputTypeChange.value) {
        inputType.value = props.type != undefined ? props.type : 'text'
    }

    placeholder.value = props.placeholder
    describeText.value = props.describeText
    checkType.value = props.checkType
    clearable.value = props.clearable === undefined ? false : props.clearable === '' ? true : props.clearable
    showPassword.value =
        props.showPassword === undefined ? false : props.showPassword === '' ? true : props.showPassword

    if (clearable.value) {
        hasIcon.value = true
    }
    if (props.contarst !== undefined) {
        if (!contarst.value && props.errTxt !== '' && isPassCheck.value) {
            isPassCheck.value = false
            errorText.value = props.errTxt
        } else if (contarst.value) {
            isPassCheck.value = true
        }
    }
    if (inputVal.value != props.modelValue && props.modelValue != '' && inputVal.value != '') {
        inputVal.value = props.modelValue
        validateInput()
    } else if (inputVal.value != props.modelValue && props.modelValue != '') {
        inputVal.value = props.modelValue
        validateInput()
    }
    if (props.modelValue == '') {
        inputVal.value = props.modelValue
        isPassCheck.value = true
    }
})

//左侧文字
// const leftContent = () =>
//     h('section', { class: ['left-content'] }, [
//         h('section', { class: [''] }, [
//             isRequired.value ? h('i', null, '*') : null,
//             title.value.length ? h('p', null, title.value) : null
//         ])
//     ])

//监听输入框获取焦点
const onFocus = () => {
    if (hasIcon.value) {
        iconVisible.value = true
    }

    inputFocusActive.value = true
}
//监听输入框失去焦点
const onBlur = (val: any) => {
    inputFocusActive.value = false
    if (hasIcon.value) {
        iconVisible.value = false
    }
    emits('blur', val.target.value)
    validateInput()
}

//监听输入框值的变化
const onChange = (e: any) => {}
const onInput = (e: any) => {
    inputVal.value = e.target.value
    inputVal.value = e.target.value
    emits('update:modelValue', e.target.value)
}

const calcPaddingRight = () => {
    if (inputFocusActive.value && inputVal.value.length) {
        if (clearable.value && showPassword.value) {
            return 'padding-3'
        } else if (!clearable.value && !showPassword.value) {
            return 'padding-1'
        } else {
            return 'padding-2'
        }
    } else {
        if (showPassword.value && inputVal.value.length) {
            return 'padding-2'
        } else {
            return 'padding-1'
        }
    }
}

function stopScrollFun(evt: Event) {
    evt = evt || window.event
    if (evt.preventDefault) {
        // Firefox
        evt.preventDefault()
        evt.stopPropagation()
    } else {
        // IE
        evt.cancelBubble = true
        evt.returnValue = false
    }
    return false
}

//input 输入框
const inputElment = () =>
    h('input', {
        class: ['inputStyle', calcPaddingRight()],
        type: inputType.value,
        value: inputVal.value,
        onFocus,
        onBlur,
        onChange,
        onInput,
        onmousewheel: stopScrollFun,
        onDOMMouseScroll: stopScrollFun,
        placeholder: placeholder.value,
        style: {
            color: textColor.value
        },
        ref: inputRef
    })

//icon 盒子
const iconItenBox = (type: string) =>
    h(
        'section',
        {
            class: ['icon-item'],
            onClick: () => {
                if (type === 'password') {
                    //
                    inputType.value = inputType.value == 'password' ? 'text' : 'password'
                    inputRef.value.focus()
                    isInputTypeChange.value = true
                } else if (type === 'clear') {
                    inputRef.value.focus()
                    inputVal.value = ''
                    emits('update:modelValue', '')
                }
            }
        },
        [
            h(
                'section',
                { class: ['icon-content', type == 'clear' ? 'clear' : '', type == 'password' ? 'password' : ''] },
                [
                    h('span', {
                        class: [
                            'iconfont',
                            type == 'clear' ? 'icon-shanchu' : '',
                            type == 'password' ? (inputType.value == 'password' ? 'icon-eye' : 'icon-eye-close') : ''
                        ],
                        style: {
                            color: textColor.value
                        }
                    })
                ]
            )
        ]
    )

//输入框盒子
const rightInputBox = () =>
    h(
        'section',
        {
            class: [
                'input-box',
                inputFocusActive.value ? 'focus' : '',
                hasIcon.value ? 'hasIcon' : '',
                border.value ? 'border' : '',
                round.value ? 'round' : '',
                !isPassCheck.value ? 'err' : ''
            ],
            style: { 'background-color': bgColor.value }
        },
        [
            h('section', { class: 'input-main' }, [inputElment()]),
            h('section', { class: ['icon-box'] }, [
                clearable.value && inputVal.value ? iconItenBox('clear') : null,
                showPassword.value && inputVal.value ? iconItenBox('password') : null
            ])
        ]
    )

//描述性文案 | 错误文案 盒子
const rightDescribeBox = () =>
    h('section', { class: ['describe'] }, [
        h('section', { class: ['hint'] }, describeText.value),
        !isPassCheck.value ? h('section', { class: ['err'] }, errorText.value) : null
    ])

//右侧输入框
const rightContent = () =>
    h(
        'section',
        {
            class: ['right-content']
        },
        [rightInputBox(), rightDescribeBox()]
    )

//渲染
const render = () =>
    h(
        'section',
        { class: ['custom-input-container', isRequired.value ? 'isRequired' : '', title.value.length ? 'title' : ''] },
        [rightContent()]
    )
//重置
const reset = () => {
    inputVal.value = ''
    isPassCheck.value = true
}

//向外暴露方法
defineExpose({ validateInput, reset })
</script>

<style lang="scss">
.custom-input-container {
    font-size: var(--cxl-size-14);
    box-sizing: border-box;
    display: flex;

    .left-content {
        height: var(--cxl-size-40);
        font-size: var(--cxl-size-14);
        display: flex;
        align-items: center;
        i {
            color: var(--cxl-color-ff5448);
            padding-right: var(--cxl-size-6);
        }
        p {
            color: var(--cxl-color-333333);
            padding-right: var(--cxl-size-6);
        }
    }
    .right-content {
        position: relative;
        width: 100%;
        flex: 1;
        .input-box {
            height: var(--cxl-size-40);

            border-radius: var(--cxl-size-6);
            box-sizing: border-box;
            padding: 0 var(--cxl-size-12);
            background-color: transparent;
            border: 1px solid transparent;
            position: relative;
            &.border {
                border-color: var(--cxl-color-d5ebda);
            }
            &.hasIcon {
                padding-left: var(--cxl-size-12);
            }
            &.round {
                border-radius: calc(var(--cxl-size-40) / 2);
            }

            &.focus {
                border-color: var(--cxl-color-primary);
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
                .icon-box {
                    .icon-content {
                        &.clear {
                            display: block;
                        }
                    }
                }
            }
            &.err {
                border-color: var(--cxl-color-ff5448);
            }

            .input-main {
                height: 100%;
                display: flex;
                align-items: center;
                position: relative;
            }

            .inputStyle {
                border: 0;
                height: 100%;
                outline: none;
                width: 100%;
                box-sizing: border-box;
                background-color: transparent;
                font-size: var(--cxl-size-14);
                cursor: pointer;
                &.padding-1 {
                    padding-right: 0;
                }
                &.padding-2 {
                    padding-right: calc(var(--cxl-size-12) + 3rem);
                }
                &.padding-3 {
                    padding-right: calc(var(--cxl-size-12) + 3rem + 3rem);
                }
            }
            .icon-box {
                display: flex;
                align-items: center;
                height: 100%;
                position: absolute;
                top: 0;
                right: 1rem;
                .icon-item {
                    width: 3rem;
                    height: 100%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }
                .icon-content {
                    &.clear {
                        display: none;
                    }
                }
            }
        }
    }
    .describe {
        box-sizing: border-box;
        padding: 0 var(--cxl-size-12);
        line-height: var(--cxl-size-22);
        font-size: var(--cxl-size-12);
        min-height: var(--cxl-size-22);
        .err {
            color: var(--cxl-color-ff5448);
        }
    }
}
</style>
